/*****************************************************************************/
/*                                                                           */
/*    Domino Operation System Communication Module                           */
/*                                                                           */
/*    Copyright (C) 2007 Laszlo Arvai                                        */
/*                                                                           */
/*    ------------------------------------------------------------------     */
/*    comIRRCTransmitter - Infra Red Remote Control transmitter routines     */
/*****************************************************************************/

///////////////////////////////////////////////////////////////////////////////
// Includes
#include <comIRRCTransmitter.h>
#include <drvIRRCTransmitter.h>
#include "drvIOConfig.h"

///////////////////////////////////////////////////////////////////////////////
// Constants
#define RFTX_BUFFER_LENGTH 10
#define RFTX_BIT_BUFFER_LENGTH 12

// status codes
#define ST_IDLE					0
#define ST_HEADER_HIGH	1
#define ST_HEADER_LOW		2
#define ST_DATA 				3

///////////////////////////////////////////////////////////////////////////////
// Module global variables
static dosDWord l_data;
static dosByte l_status;
static dosByte l_bit_index;
static dosByte l_bit_state;
static comIRRCTXProtocol l_protocol;

///////////////////////////////////////////////////////////////////////////////
// Initialize
void comIRRCTXInit(void)
{
	drvIRRCTXInit();
}

///////////////////////////////////////////////////////////////////////////////
// Set protocol
void comIRRCTXSetProtocol( comIRRCTXProtocol* in_protocol )
{
	l_protocol = *in_protocol;
}

///////////////////////////////////////////////////////////////////////////////
// Send Data
void comIRRCTXSendData( dosDWord in_data )
{
	// init
	l_bit_index = 0;
	l_bit_state = 0;

	// setup pulse generator
	drvIRRCTXSetupPulseGenerator( l_protocol.Frequency, l_protocol.DutyCycle );

	// start with header pulse
	l_data = in_data;
	l_status = ST_HEADER_HIGH;
	drvIRRCTXStartPulseGenerator();
	drvIRRCTXSetTimerCallback((dosWord)l_protocol.HeaderPulse * 100u );
}

///////////////////////////////////////////////////////////////////////////////
// Is Transmitter Busy
dosBool comIRRCTXIsTransmitterBusy(void)
{
	return l_status != ST_IDLE;
}


///////////////////////////////////////////////////////////////////////////////
// Timer callback
void comIRRCTXTimerCallback(void)
{
	switch( l_status )
	{
		// if idle
		case ST_IDLE:
			break;

		// if header pulse finished
		case ST_HEADER_HIGH:
			l_status = ST_HEADER_LOW;
			drvIRRCTXStopPulseGenerator();
			drvIRRCTXAddTimerCallback((dosWord)l_protocol.HeaderSpace * 100u );
			break;

		// if header space finished
		case ST_HEADER_LOW:
			// init bit sending
			l_bit_index = 0;
			l_bit_state = 0;
			l_status = ST_DATA;

			// break;  NO BREAK

		// data sending
		case ST_DATA:
			if( l_bit_state == 0 )
			{
				// send pulse part
				drvIRRCTXStartPulseGenerator();
				if( (l_data & (1<<l_bit_index)) == 0 )
					drvIRRCTXAddTimerCallback((dosWord)l_protocol.Data0Pulse * 100u );
				else
					drvIRRCTXAddTimerCallback((dosWord)l_protocol.Data1Pulse * 100u );

				l_bit_state = 1;
			}
			else
			{
				// send space part
				drvIRRCTXStopPulseGenerator();

				if( l_bit_index >= l_protocol.Bits )
				{
					// if there is no more bits to send
					l_status = ST_IDLE;
					l_bit_index = 0;
					l_bit_state = 0;
				}
				else
				{
					// data space
					if( (l_data & (1<<l_bit_index)) == 0 )
						drvIRRCTXAddTimerCallback((dosWord)l_protocol.Data0Space * 100u );
					else
						drvIRRCTXAddTimerCallback((dosWord)l_protocol.Data1Space * 100u );

					// next bit
					l_bit_state = 0;
					l_bit_index++;
				}
			}
			break;
	}
}

